<!--
 * @Author: JiraiyaChen 979526234@qq.com
 * @Date: 2025-03-24 09:31:54
 * @LastEditors: JiraiyaChen 979526234@qq.com
 * @LastEditTime: 2025-07-24 13:39:40
 * @Description: 评分点
-->

<template>
  <ClDialog v-bind="$attrs" :title="getTitle" width="1600px" :before-close="beforeClose">
    <OptionsBtn
      :collapse-flag="collapseFlag"
      :show-collapse="collapseItemList.length > 0"
      @on-add="onAdd"
      @upload-success="(res) => uploadSuccess(res)"
      @handle-collapse="handleCollapse"
    />
    <ClBar :loading="loaded" bar-height="650px">
      <div v-if="collapseItemList.length > 0" class="p-3">
        <el-collapse ref="collapseRef" v-model="activeNames" class="collapse-one">
          <el-collapse-item
            v-for="(itemOne, indexOne) in collapseItemList"
            :id="itemOne.orderNo"
            :key="itemOne.orderNo"
            :title="getCollapseTitle(indexOne)"
            :name="itemOne.orderNo"
          >
            <CollapseForm
              ref="collapseFormRef"
              :show-add-btn="true"
              :form-data="itemOne.formData"
              :mark-mode-code="props.info.markModeCode"
              @add-item="addItem(itemOne, '二级评分点')"
              @delete-item="deleteItem(collapseItemList, indexOne, itemOne)"
              @value-change="(res) => valueChange(itemOne, res)"
            />
            <div v-if="itemOne.children?.length > 0">
              <el-collapse v-model="activeNames2" class="collapse-two">
                <el-collapse-item
                  v-for="(itemTwo, indexTwo) in itemOne.children"
                  :id="itemTwo.orderNo"
                  :key="itemTwo.orderNo"
                  :title="getCollapseTitle2(indexOne, indexTwo)"
                  :name="itemTwo.orderNo"
                >
                  <CollapseForm
                    ref="collapseFormRef2"
                    :show-add-btn="true"
                    :form-data="itemTwo.formData"
                    :mark-mode-code="props.info.markModeCode"
                    @add-item="addItem(itemTwo, '三级评分点')"
                    @delete-item="deleteItem(itemOne.children, indexTwo, itemTwo)"
                    @value-change="(res) => valueChange(itemTwo, res)"
                  />
                  <div v-if="itemTwo.children?.length > 0">
                    <el-collapse v-model="activeNames3" class="collapse-three">
                      <el-collapse-item
                        v-for="(itemThree, indexThree) in itemTwo.children"
                        :id="itemThree.orderNo"
                        :key="itemThree.orderNo"
                        :title="getCollapseTitle3(indexOne, indexTwo, indexThree)"
                        :name="itemThree.orderNo"
                      >
                        <CollapseForm
                          ref="collapseFormRef3"
                          :show-add-btn="false"
                          :form-data="itemThree.formData"
                          :mark-mode-code="props.info.markModeCode"
                          @delete-item="deleteItem(itemTwo.children, indexThree, itemThree)"
                          @value-change="(res) => valueChange(itemThree, res)"
                        />
                      </el-collapse-item>
                    </el-collapse>
                  </div>
                </el-collapse-item>
              </el-collapse>
            </div>
          </el-collapse-item>
        </el-collapse>
      </div>
      <div v-else>
        <div class="p-3">
          <div class="text-center font-bold">暂无评分点</div>
        </div>
      </div>
    </ClBar>
    <template #footer>
      <span class="dialog-footer">
        <OptionsBtn
          :collapse-flag="collapseFlag"
          :show-collapse="collapseItemList.length > 0"
          @on-add="onAdd"
          @upload-success="(res) => uploadSuccess(res)"
          @handle-collapse="handleCollapse"
        />
        <div>
          <el-button @click="onClose">取消</el-button>
          <el-button type="primary" @click="onSure">保存</el-button>
        </div>
      </span>
    </template>
  </ClDialog>
</template>

<script setup lang="ts">
import { computed, onMounted, ref } from 'vue'
import { ElMessageBox } from 'element-plus'
import OptionsBtn from './components/OptionsBtn.vue'
import CollapseForm from './components/CollapseForm.vue'
import { addChildrenFlag, compareArrays, handlePointInfoViewFlat, judgeFormValidate, judgeMaxScore } from './data'
import { pointInfoSaveUpdate, pointInfoView } from '@/api/basic-settings-module'
import { projectPointInfoSaveTree, projectPointInfoView } from '@/api/project-scoring-standard-configuration'
interface PointInfo {
  formData: {
    id?: string
    createTime?: string
    createUser?: string
    updateTime?: string
    updateUser?: string
    beenDeleted?: boolean
    [key: string]: any
  }
  children?: PointInfo[]
  [key: string]: any
}

onMounted(async () => {
  init()
})
// 复制评分点列表
const copyCollapseItemList = ref<any[]>([])
const loaded = ref(false)
const init = async () => {
  try {
    loaded.value = false
    if (props.type === '评分点' && props.info.id) {
      const res: any = await pointInfoView({ itemId: props.info.id })
      collapseItemList.value = handlePointInfoView(res)
    }
    if (props.type === '项目评分点' && props.info.id) {
      const res: any = await projectPointInfoView({ itemId: props.info.id })
      copyCollapseItemList.value = handlePointInfoViewFlat(cloneDeep(res))
      const renderRes = handlePointInfoView(res)
      collapseItemList.value = renderRes
    }
    loaded.value = true
    // 打开所有折叠
    setTimeout(() => {
      openAll()
    }, 100)
  } catch (error: any) {
    loaded.value = true
    console.log(error, 'error')
  }
}
// 处理评分点列表 生成树形结构
const handlePointInfoView = (res: PointInfo[]): PointInfo[] => {
  return res.map((item: PointInfo) => {
    const { formData, children, ...rest } = item
    const newFormData = { ...formData }
    if (props.type === '评分点') {
      // 接口
      delete newFormData.id
    }
    delete newFormData.createTime
    delete newFormData.createUser
    delete newFormData.updateTime
    delete newFormData.updateUser
    delete newFormData.beenDeleted

    return {
      ...rest,
      formData: newFormData,
      children: children ? handlePointInfoView(children) : undefined
    }
  })
}

const beforeClose = (done) => {
  ElMessageBox.confirm('确定关闭吗？', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  }).then(() => {
    if (updateFlag.value) {
      emit('atClose', 'refresh-table')
    } else {
      emit('atClose')
    }
  })
}

const collapseRef = ref<any>(null)
// 评分点表单
const collapseFormRef = ref<any>(null)
const collapseFormRef2 = ref<any>(null)
const collapseFormRef3 = ref<any>(null)
// 多重表单 验证评分点表单
const handleFormValidate = async () => {
  let tempForm1 = true
  let tempForm2 = true
  let tempForm3 = true
  if (collapseFormRef.value) {
    tempForm1 = await judgeFormValidate(collapseFormRef.value)
  }
  if (collapseFormRef2.value) {
    tempForm2 = await judgeFormValidate(collapseFormRef2.value)
  }
  if (collapseFormRef3.value) {
    tempForm3 = await judgeFormValidate(collapseFormRef3.value)
  }
  if (tempForm1 && tempForm2 && tempForm3) {
    return true
  }
  return false
}

// 评分点列表 页面显示数据
const collapseItemList = ref<any[]>([])
// 是否折叠
const collapseFlag = ref(true)
// 评分点折叠
const activeNames = ref<any[]>([])
const activeNames2 = ref<any[]>([])
const activeNames3 = ref<any[]>([])
const handleCollapse = () => {
  collapseFlag.value = !collapseFlag.value
  if (collapseFlag.value) {
    openAll()
  } else {
    closeAll()
  }
}
const closeAll = () => {
  activeNames.value = []
  activeNames2.value = []
  activeNames3.value = []
}
const openAll = () => {
  collapseItemList.value.forEach((item) => {
    if (item.children?.length > 0) {
      item.children.forEach((item2) => {
        activeNames2.value.push(item2.orderNo)
        if (item2.children?.length > 0) {
          item2.children.forEach((item3) => {
            activeNames3.value.push(item3.orderNo)
          })
        }
      })
    }
    activeNames.value.push(item.orderNo)
  })
}
// 设置默认表单数据
const getDefaultFormData = () => {
  if (props.info.markModeCode === 'CONFORM') {
    return {
      name: '',
      standard: '',
      maxScore: null,
      minScore: null,
      score: '',
      typeCode: 'OBJECTIVE',
      itemId: ''
    }
  }
  if (props.info.markModeCode === 'DIRECT') {
    return {
      name: '',
      standard: '',
      typeCode: '',
      itemId: ''
    }
  }
  return {}
}
const scrollToElement = (orderNo: string) => {
  setTimeout(() => {
    document.getElementById(orderNo)?.scrollIntoView({ behavior: 'smooth' })
  }, 100)
}
// 顶部新增，序号自增
const onAdd = () => {
  const orderNo = new Date().getTime()
  // 只有符合性打分的时候 评分点类型为 客观分
  collapseItemList.value.push({
    children: [],
    formData: { ...getDefaultFormData(), orderNo },
    orderNo,
    parentNo: -1,
    VUE_DATA: true
  })
  activeNames.value.push(orderNo)
  scrollToElement(orderNo.toString())
}
// 新增评分点
const addItem = (item: any, name: string) => {
  const orderNo = new Date().getTime()
  // 只有符合性打分的时候 评分点类型为 客观分
  const temp: any = {
    children: [],
    formData: { ...getDefaultFormData(), orderNo },
    orderNo,
    parentNo: item.orderNo,
    VUE_DATA: true
  }
  if (item.children) {
    item.children.push(temp)
  } else {
    item.children = [temp]
  }
  // 设置折叠 展开
  if (name === '二级评分点') {
    activeNames2.value.push(orderNo)
  } else if (name === '三级评分点') {
    activeNames3.value.push(orderNo)
  }
  scrollToElement(orderNo.toString())
}
// 删除评分点
const deleteItem = async (fatherArr: any, index: number, item: any) => {
  fatherArr.splice(index, 1)
}

const handleUploadData = (data: any) => {
  return data.map((m) => {
    return {
      ...m,
      VUE_DATA: true,
      children: m.children ? handleUploadData(m.children) : undefined
    }
  })
}

// 上传成功
const uploadSuccess = async (data: any) => {
  const tempData = handleUploadData(data)
  collapseItemList.value = [...collapseItemList.value, ...tempData]
}

// 响应表单值
const valueChange = (item: any, res: any) => {
  item.formData = res
}

const updateFlag = ref(false)
const onClose = () => {
  ElMessageBox.confirm('确定关闭吗？', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  }).then(() => {
    if (updateFlag.value) {
      emit('atClose', 'refresh-table')
    } else {
      emit('atClose')
    }
  })
}

const onSure = async () => {
  try {
    if (props.type === '评分点') {
      const formValidateRes = await handleFormValidate()
      if (!formValidateRes) {
        elMessage('请检查评分点表单', 'error')
        return
      }
      const collapseItemListChild = addChildrenFlag(cloneDeep(collapseItemList.value))
      await pointInfoSaveUpdate({
        itemId: props.info.id,
        pointTree: collapseItemListChild
      })
    }
    if (props.type === '项目评分点') {
      const formValidateRes = await handleFormValidate()
      if (!formValidateRes) {
        elMessage('请检查评分点表单', 'error')
        return
      }
      // 最高分校验
      const { isValid, errorNodes } = judgeMaxScore(collapseItemList.value)
      if (!isValid) {
        elMessage(`最高分错误：\n${errorNodes.join('\n')}`, 'error')
        return
      }
      // 添加childrenFlag
      const collapseItemListChild = addChildrenFlag(cloneDeep(collapseItemList.value))
      const currentList = handlePointInfoViewFlat(collapseItemListChild)
      const res = compareArrays(copyCollapseItemList.value, currentList)
      await projectPointInfoSaveTree({
        itemId: props.info.id,
        ...res,
        validList: collapseItemList.value
      })
    }
    updateFlag.value = true
    await init()
  } catch (error: any) {
    elMessage(JSON.stringify(error), 'error')
  }
}

// 获取最高分
const getScore = (arr: any) => {
  let sum = 0
  arr.forEach((item) => {
    sum += Number(item.formData.maxScore ?? 0)
    if (item.children?.length > 0) {
      sum += getScore(item.children)
    }
  })
  return sum
}
onMounted(() => {})

const getTitle = computed(() => {
  return props.type
})
// 获取折叠标题
const getCollapseTitle = (indexOne: number) => {
  return String(indexOne + 1)
}
const getCollapseTitle2 = (indexOne: number, indexTwo: number) => {
  return `${String(indexOne + 1)}.${String(indexTwo + 1)}`
}
const getCollapseTitle3 = (indexOne: number, indexTwo: number, indexThree: number) => {
  return `${String(indexOne + 1)}.${String(indexTwo + 1)}.${String(indexThree + 1)}`
}

interface infoType {
  [props: string]: any
}
const props = defineProps<{ info: infoType; type: string }>()

const emit = defineEmits<{
  (e: 'atClose', str?: string | undefined): void
  (e: 'reFreshTable', str?: string | undefined): void
}>()
</script>

<style scoped lang="scss">
.collapse-one {
  border-left: 2px solid #a0cfff !important;
  padding: 10px;
}
.collapse-two {
  border-left: 2px solid #b3e19d !important;
  padding: 10px;
}
.collapse-three {
  border-left: 2px solid #f3d19e !important;
  padding: 10px;
}
:deep(.el-collapse-item__header) {
  padding-left: 10px !important;
  font-size: 14px !important;
  font-weight: 600 !important;
}
</style>
